home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / crypt / idea.lha / crypt.c next >
C/C++ Source or Header  |  1992-08-26  |  5KB  |  156 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /*               C R Y P T O G R A P H I C - A L G O R I T H M S              */
  4. /*                                                                            */
  5. /******************************************************************************/
  6. /* Author:       Richard De Moliner (demoliner@isi.ethz.ch)                   */
  7. /*               Signal and Information Processing Laboratory                 */
  8. /*               Swiss Federal Institute of Technology                        */
  9. /*               CH-8092 Zuerich, Switzerland                                 */
  10. /* Last Edition: 13 May 1992                                                  */
  11. /* System:       AMIGA, SAS (Lattice) C-Compiler, AmigaDOS 2.0                */
  12. /******************************************************************************/
  13. #include "crypt.h"
  14.  
  15. #define mulMod        0x10001 /* 2**16 + 1                                    */
  16. #define addMod        0x10000 /* 2**16                                        */
  17. #define ones           0xFFFF /* 2**16 - 1                                    */
  18.  
  19. #define nofKeyPerRound      6 /* number of used keys per round                */
  20. #define nofRound            8 /* number of rounds                             */
  21.  
  22. /******************************************************************************/
  23. /*                          A L G O R I T H M                                 */
  24. /******************************************************************************/
  25. /* multiplication                                                             */
  26.  
  27. u_int32 Mul(u_int32 a, u_int32 b)
  28.  
  29. { int32 p;
  30.   u_int32 q;
  31.   
  32.   if (a == 0)
  33.     p = mulMod - b; 
  34.   else if (b == 0) 
  35.     p = mulMod - a;
  36.   else {
  37.      q = a * b;
  38.      p = (q & ones) - (q >> 16);
  39.      if (p <= 0)
  40.        p += mulMod;
  41.   }
  42.   return (u_int32)(p & ones);
  43. } /* Mul */
  44.  
  45. /******************************************************************************/
  46. /* compute inverse of 'x' by Euclidean gcd algorithm                          */
  47.  
  48. u_int16 MulInv(u_int16 x)
  49.  
  50. { int32 n1, n2, q, r, b1, b2, t;
  51.  
  52.   if (x == 0)
  53.     return 0;
  54.   n1 = mulMod;
  55.   n2 = (int32)x;
  56.   b2 = 1; b1 = 0;
  57.   do {
  58.     r = (n1 % n2);
  59.     q = (n1 - r) / n2;
  60.     if (r == 0) {
  61.       if (b2 < 0)
  62.         b2 = mulMod + b2;
  63.     }
  64.     else {
  65.       n1 = n2;
  66.       n2 = r;
  67.       t = b2;
  68.       b2 = b1 - q * b2;
  69.       b1 = t;
  70.     }
  71.   } while (r != 0);
  72.   return (u_int16)b2;
  73. } /* MulInv */
  74.  
  75. /******************************************************************************/
  76. /* encryption and decryption algorithm IDEA                                   */
  77.  
  78. void  Idea(u_int16 *dataIn, u_int16 *dataOut, u_int16 *key)
  79.  
  80. { register u_int32 round, x0, x1, x2, x3, t0, t1;
  81.  
  82.   x0 = (u_int32)*(dataIn++);
  83.   x1 = (u_int32)*(dataIn++);
  84.   x2 = (u_int32)*(dataIn++);
  85.   x3 = (u_int32)*(dataIn);
  86.   for (round = nofRound; round > 0; round--) {
  87.     x0 = Mul(x0, (u_int32)*(key++));
  88.     x1 = (x1 + (u_int32)*(key++)) & ones;
  89.     x2 = (x2 + (u_int32)*(key++)) & ones;
  90.     x3 = Mul(x3, (u_int32)*(key++));
  91.     t0 = Mul((u_int32)*(key++), x0 ^ x2);
  92.     t1 = Mul((u_int32)*(key++), (t0 + (x1 ^ x3)) & ones);
  93.     t0 = (t0 + t1) & ones;
  94.     x0 ^= t1;
  95.     x3 ^= t0;
  96.     t0 ^= x1;
  97.     x1 = x2 ^ t1;
  98.     x2 = t0;
  99.   }
  100.   *(dataOut++) = (u_int16)(Mul(x0, (u_int32)*(key++)));
  101.   *(dataOut++) = (u_int16)((x2 + (u_int32)*(key++)) & ones);
  102.   *(dataOut++) = (u_int16)((x1 + (u_int32)*(key++)) & ones);
  103.   *(dataOut) = (u_int16)(Mul(x3, (u_int32)*key));
  104. } /* Idea */
  105.  
  106. /******************************************************************************/
  107. /* invert decryption / encrytion key for IDEA                                 */
  108.  
  109. void InvertIdeaKey(u_int16 *key, u_int16 *invKey)
  110.  
  111. { register int  i;
  112.   key_t(dk);
  113.  
  114.   dk[nofKeyPerRound * nofRound + 0] = MulInv(*(key++));
  115.   dk[nofKeyPerRound * nofRound + 1] = (addMod - *(key++)) & ones;
  116.   dk[nofKeyPerRound * nofRound + 2] = (addMod - *(key++)) & ones;
  117.   dk[nofKeyPerRound * nofRound + 3] = MulInv(*(key++));
  118.   for (i = nofKeyPerRound * (nofRound - 1); i >= 0; i -= nofKeyPerRound) {
  119.     dk[i + 4] = *(key++);
  120.     dk[i + 5] = *(key++);
  121.     dk[i + 0] = MulInv(*(key++));
  122.     if (i > 0) {
  123.       dk[i + 2] = (addMod - *(key++)) & ones;
  124.       dk[i + 1] = (addMod - *(key++)) & ones;
  125.     }
  126.     else {
  127.       dk[i + 1] = (addMod - *(key++)) & ones;
  128.       dk[i + 2] = (addMod - *(key++)) & ones;
  129.     }
  130.     dk[i + 3] = MulInv(*(key++));
  131.   }
  132.   for (i = 0; i < keyLen; i++)
  133.     invKey[i] = dk[i]; 
  134. } /* InvertIdeaKey */
  135.  
  136.  
  137. /******************************************************************************/
  138. /* expand user key of 128 bits to full key of 832 bits                        */
  139.  
  140. void ExpandUserKey(u_int16 *userKey, u_int16 *key)
  141.  
  142. { register int i;
  143.  
  144.   for (i = 0; i < userKeyLen; i++)
  145.     key[i] = userKey[i];
  146.   /* shifts */
  147.   for (i = userKeyLen; i < keyLen; i++) {
  148.     if ((i + 2) % 8 == 0)                    /* for key[14],key[22],..  */
  149.       key[i] = ((key[i - 7] & 127) << 9) ^ (key[i - 14] >> 7); 
  150.     else if ((i + 1) % 8 == 0)               /* for key[15],key[23],..  */
  151.       key[i] = ((key[i - 15] & 127) << 9) ^ (key[i - 14] >> 7); 
  152.     else
  153.       key[i] = ((key[i - 7] & 127) << 9 ) ^ (key[i - 6] >> 7);
  154.    }
  155. } /* ExpandUserKey */
  156.